/**
 *	计划任务服务
 *	开发者：雨中磐石
 *	地址：www.rockoa.com
 *	日期：2023-07-19
 */

package com.framerock.server;

import com.framerock.baselib.CDate;
import com.framerock.baselib.CLog;
import com.framerock.baselib.Config;
import com.framerock.baselib.Rock;
import com.framerock.db.DB;
import com.framerock.db.DBConn;
import com.framework.Model.ModelRemind;

import java.net.Socket;
import java.util.ArrayList;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 计划任务服务
 * */
public class TaskServer {

    private static int nowtime = 0,nowtimes=0,runcount = 0;

    /**
     * 是否在运行
     * */
    private static boolean runbool = false;

    /**
     * 是否设置停止
     * */
    private static boolean stopbool=false;

    /**
     * 运行的线程池
     * */
    private static ScheduledExecutorService executorService = null;

    //运行队列
    private static ArrayList<Map<String, String>> runList = null;

    /**
     * 打开计划任务主服务
     * */
    public static void start()
    {
        if(Config.getConfig("task.start").equals("false"))return;//不启用
        if(executorService == null)executorService = Executors.newScheduledThreadPool(1);
        executorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                startTasks();
            }
        }, 1000, 1000, TimeUnit.MILLISECONDS);
    }

    /**
     * 重启计划任务
     * */
    public static void restart()
    {
        if(!stopbool)stop();
        stopbool = false;
        start();
    }

    /**
     * 停止计划任务
     * */
    public static void stop()
    {
        stopbool= true;
        runbool = false;
        if(executorService != null)executorService.shutdown();
        executorService = null;
        CLog.print("---taskserver stop ---");
        nowtime = 0;
    }

    /**
     * 持续运行的
     * */
    private static void startTasks() {
        if(nowtime == 0)CLog.print("[pid:"+ Rock.getProcessId()+"]---taskserver runing ---");
        if(stopbool)stop();
        if(runbool || stopbool)return;runbool = true;
        if(nowtime <= 0 ) {
            nowtimes    = Integer.parseInt(CDate.gettimes());
            if(nowtime == 0) {
                nowtime = nowtimes + 0;
            }else{
                String nowstr = CDate.now("Y-m-d H:i:00", "");//从00秒开始，防止跳过
                nowtime = Integer.parseInt(CDate.gettimes(nowstr));
            }
            getRemindtime();
        }else{
            nowtime ++;
            nowtimes ++;
        }
        if(runcount > 0) {
            Map<String, String> rs;
            ArrayList<Map<String, String>> rslist = null;
            for(int i=0;i<runList.size();i++){
                rs = runList.get(i);
                if(Rock.equals(rs.get("runtime"), nowtime+"")){
                    if(rslist == null)rslist = Rock.getMapList();
                    rslist.add(rs);
                    runcount --;
                }
            }
            if(rslist != null){
                ThreadServer.addThread(new myRunnable(rslist));
            }
        }else{
            runList = null;
        }
        if(nowtimes % 60 == 59)nowtime = -1;//为啥是59?因为下一秒就是00分，需要重新读取列表
        runbool = false;
    }


    /**
     * 获取运行的队列1分钟内运行列表
     * */
    private static void getRemindtime(){
        runcount    = 0;
        DBConn ndb  = DB.getDbobj();
        runList     = ModelRemind.get(ndb).getRunList();
        ndb.close();
        if(runList != null)runcount = runList.size();
    }

    //运行计划任务
    private static void runRemindtime(ArrayList<Map<String, String>> rslist, Thread thread){
        ModelRemind remindobj = ModelRemind.get(DB.getDbobj());
        String ostr = "",bstr;
        Map<String, String> rs;
        for(int i=0; i<rslist.size(); i++) {
            rs   = rslist.get(i);
            bstr = remindobj.runstart(rs);
            ostr += ""+rs.get("id")+"="+bstr+";";
        }
        remindobj.close();
        if(thread != null)thread.interrupt();
    }

    //线程池使用
    private static class myRunnable implements Runnable {
        private ArrayList<Map<String, String>> datarslist;
        public myRunnable(ArrayList<Map<String, String>> rslist){
            datarslist = rslist;
        }
        @Override
        public void run() {
            runRemindtime(datarslist, null);
        }
    }
}
